package internal

import (
	"github.com/golang-module/carbon"
	"github.com/maja42/goval"
	"github.com/shopspring/decimal"
	"github.com/thoas/go-funk"
	"time"
	"zt-compute/config"
)

type DataItem struct {
	IndexId       string    `json:"index_id" db:"index_id"`
	TimeCode      string    `json:"time_code" db:"time_code"`
	BeginTime     time.Time `json:"begin_time" db:"begin_time"`
	EndTime       time.Time `json:"end_time" db:"end_time"`
	Value         float64   `json:"value" db:"value"`
	Quality       string    `json:"quality" db:"quality"`
	CreateTime    time.Time `json:"create_time" db:"create_time"`
	UpdateTime    time.Time `json:"update_time" db:"update_time"`
	TimeType      string    `json:"time_type" db:"time_type"`
	DataTime      time.Time `json:"data_time" db:"data_time"`
	TeamId        string    `json:"team_id" db:"team_id"`
	WorkforceId   string    `json:"workforce_id" db:"workforce_id"`
	InpIndexFlag  string    `json:"inp_index_flag" db:"inp_index_flag"`
	InpIndexValId string    `json:"inp_index_val_id" db:"inp_index_val_id"`
}

func buildDataItemList(begin carbon.Carbon, end carbon.Carbon, dataTime carbon.Carbon,
	tagValueMap map[string]interface{}, indexes []config.Index, workforces []WorkforceManagement) {
	eval := goval.NewEvaluator()
	timeCode := dataTime.Time.Format("D20060102")
	insertTime := time.Unix(time.Now().Unix(), 0)
	result := make([]DataItem, 0)
	workMap := funk.Map(workforces, func(x WorkforceManagement) (uint32, string) {
		return x.ProcessId, x.WorkforceId
	}).(map[uint32]string)
	for _, item := range indexes {
		// 判断装置id是否对应班次的装置id,如果不对应忽略这条数据
		if _, ok := workMap[item.ProcessId]; !ok {
			MyLog.Warn("没有找到匹配的装置id","装置id", item.ProcessId)
			continue
		}

		// 计算数据
		calcValue, err := eval.Evaluate(item.Expression, tagValueMap, nil)
		quality:="good"
		if err != nil {
			MyLog.Error("计算出错", err,"表达式", item.Expression)
			calcValue = 0.0
			quality="bad"
		}
		value, _ := decimal.NewFromFloat(calcValue.(float64)).Round(5).Float64()
		dataItem := DataItem{
			IndexId:       item.Id,
			TimeCode:      timeCode,
			BeginTime:     begin.Time,
			EndTime:       end.Time,
			Value:         value,
			Quality:       quality,
			TimeType:      "DAY",
			DataTime:      dataTime.Time,
			CreateTime:    insertTime,
			UpdateTime:    insertTime,
			TeamId:        "",
			WorkforceId:   workMap[item.ProcessId],
			InpIndexFlag:  "ZDCJ",
			InpIndexValId: "1",
		}
		result = append(result, dataItem)
	}
	MyLog.Debug("数据构建完成","数据", result)

	insertList := funk.Chunk(result, 150)

	for i := range insertList.([][]DataItem) {
		err:=insertBatch(insertList.([][]DataItem)[i])
		if err!=nil{
			MyLog.Error("insertBatch",err)
		}
	}
}

func insertBatch(list []DataItem) error {
	strInsert := "INSERT INTO " + config.MyConfig.DBInsertTableName + "(index_id, time_code, begin_time, end_time, value, quality, create_time, update_time, time_type, data_time, team_id, workforce_id, inp_index_flag, inp_index_val_id) VALUES " +
		"(:index_id, :time_code, :begin_time, :end_time, :value, :quality, :create_time, :update_time, :time_type, " +
		":data_time, :team_id, :workforce_id, :inp_index_flag, " +
		":inp_index_val_id) ON CONFLICT ( index_id, time_code,workforce_id ) DO UPDATE SET value = EXCLUDED.value," +
		"update_time = now()"
	_, err := config.MyConfig.SqlEngine.NamedExec(strInsert, list)
	return err
}
